package gbench.appdemo.ggplot.layer.geom;

import java.util.Arrays;
import java.util.stream.Stream;

import javax.imageio.ImageIO;

import gbench.common.matlib.data.DataReader.DFrame;
import gbench.common.matlib.img.ImageOps;
import gbench.common.matlib.matrix.MatrixOps.Tuple2;
import gbench.appdemo.ggplot.aes.Aesthetics;
import gbench.appdemo.ggplot.layer.Layer;
import gbench.appdemo.ggplot.plot.panel.SinkPanel;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.net.HttpURLConnection;  
import java.net.URL;  

import static gbench.common.matlib.matrix.MatrixOps.Tuple2.*;

/**
 * 图片
 * @author gbench
 *
 */
public class GeomImage  extends Layer{

    public GeomImage(DFrame dataframe,Aesthetics mappings) {
        super(mappings, dataframe);
    }
    
    public static GeomImage geom_img(DFrame dataframe,Aesthetics mappings) {
        return new GeomImage(dataframe,mappings);
    }
    
    public static GeomImage geom_img(Aesthetics mappings) {
        return new GeomImage(null,mappings);
    }
    
    /**
     * 图层计算
     * 
     * @return
     */
    @Override
    public Stream<Tuple2<Tuple2<Double, Double>, int[]>> evaluate(SinkPanel panel) {
        final var width = panel.getWidth();
        final var height = panel.getHeight();
        final var path = this.getAes("path", (String)null);
        final var rgbinfo = isURL(path) ? ImageOps.img2rgbinfo(getUrlImage(path)) : ImageOps.img2rgbinfo(path);
        if(rgbinfo==null)return Stream.of();
        final var w = rgbinfo.i4("width");
        final var h = rgbinfo.i4("height");
        final var xratio = 1d/w*width;
        final var yratio = 1d/h*height;
        
        return ImageOps.rgbinfo2xyrgbS(rgbinfo,pixel->{
            final var clr = Arrays.copyOfRange(pixel, 2, pixel.length);
            final var coord = TUP2(pixel[0]*xratio,height-pixel[1]*yratio);
            return TUP2(coord,clr);
        });
    }
    
    /**
     * 判断一个字符串是否为url
     * @param str String 字符串
     * @return boolean 是否为url
     * @author peng1 chen
     * **/
    public static boolean isURL(String str){
        //转换为小写
        str = str.toLowerCase();
        String regex = "^((https|http|ftp|rtsp|mms)?://)"  //https、http、ftp、rtsp、mms
                + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@  
               + "(([0-9]{1,3}\\.){3}[0-9]{1,3}" // IP形式的URL- 例如：199.194.52.184  
                 + "|" // 允许IP和DOMAIN（域名）
                 + "([0-9a-z_!~*'()-]+\\.)*" // 域名- www.  
                 + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\." // 二级域名  
                + "[a-z]{2,6})" // first level domain- .com or .museum  
                + "(:[0-9]{1,5})?" // 端口号最大为65535,5位数
                + "((/?)|" // a slash isn't required if there is no file name  
                + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";  
        return  str.matches(regex);
    }
    
    /**
     * 读取网络图片
     * @param destUrl
     * @return
     */
    public static BufferedImage getUrlImage(String destUrl) {
        BufferedImage bimg = null;
        try {
            var url = new URL(destUrl);
            var httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            var bis = new BufferedInputStream(httpUrl.getInputStream());
            bimg = ImageIO.read(bis);
            bis.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
        return bimg;
    }

   /**
    * 下载图片
    * @author gbench
    *
    */
    public static class DownloadImage {

        /**
         * 下载文件
         * @param destUrl
         */
        public void saveToFile(String destUrl,String path) {
            FileOutputStream fos = null;
            BufferedInputStream bis = null;
            HttpURLConnection httpUrl = null;
            URL url = null;
            int BUFFER_SIZE = 1024;
            byte[] buf = new byte[BUFFER_SIZE];
            int size = 0;
            try {
                url = new URL(destUrl);
                httpUrl = (HttpURLConnection) url.openConnection();
                httpUrl.connect();
                bis = new BufferedInputStream(httpUrl.getInputStream());
                fos = new FileOutputStream(path);
                while ((size = bis.read(buf)) != -1) {
                    fos.write(buf, 0, size);
                }
                fos.flush();
            } catch (IOException e) {
            } catch (ClassCastException e) {
            } finally {
                try {
                    fos.close();
                    bis.close();
                    httpUrl.disconnect();
                } catch (IOException e) {
                } catch (NullPointerException e) {
                }
            }
        }
    }

}
